﻿using System;
using RayDen.Library.Components.Surface;
using RayDen.Library.Core;
using RayDen.Library.Core.Primitives;
using RayDen.Library.Entity.Scene;
using RayDen.RayEngine.Core.Surface;
using RayDen.RayEngine.Core.Types;

namespace RayDen.RayEngine.Core.Surface
{
    public class SpecularReflectionBrdf : BaseBxdf
    {
        public SpecularReflectionBrdf() { }
        public SpecularReflectionBrdf(ref RayHit rh, ref RayData ray, ref Normal ng, ref Normal ns, ref UV texCoord, MaterialInfo mi, SurfaceTextureInfo texData, bool fromLight)
            : base(ref rh, ref ray, ref ng, ref ns, ref texCoord, mi, texData, fromLight)
        {
        }

        public override bool IsDelta
        {
            get { return true; }
        }

        protected override RgbSpectrum Sample(ref HitPointInfo HitPoint, ref Vector localFixedDir, out Vector localSampledDir, float u0, float u1, out float pdfW, out float absCosDir, out BsdfEvent _event)
        {
            _event = this.Type.TypeToEvent();

            localSampledDir = new Vector(-localFixedDir.x, -localFixedDir.y, localFixedDir.z);
            pdfW = 1f;

            absCosDir = Math.Abs(localSampledDir.z);
            var kr = (RgbSpectrum)TexData.Specular;

            // The absCosSampledDir is used to compensate the other one used inside the integrator
            return kr / absCosDir;
        }

        protected override RgbSpectrumInfo Evaluate(ref HitPointInfo HitPoint, ref Vector localLightDir, ref Vector localEyeDir, out BsdfEvent _event, out float directPdfW, out float reversePdfW)
        {
            _event = this.Type.TypeToEvent();
            directPdfW = 0f;
            reversePdfW = 0f;
            return RgbSpectrumInfo.Black;
        }

        public override BrdfType Type
        {
            get { return BrdfType.Specular | BrdfType.Reflection; }
        }

        public override bool IsLightSource()
        {
            return false;
        }

        public override bool IsDiffuse()
        {
            return false;
        }

        public override bool IsRefractive()
        {
            return false;
        }

        public override bool IsSpecular()
        {
            return true;
        }
    }
}